import * as cloudDb from '@agconnect/database-server';
import { resource } from './model/resource';
import { DetailResp } from './model/DetailResp';
import { user_like } from './model/user_like';
import { collect } from './model/collect';
import { user_history } from './model/user_history';
import { ResourceResp } from './model/ResourceResp';
import * as agc from '@agconnect/common-server';
import * as Utils from './utils/Utils.js';

const ZONE_NAME = "HarmonyOSDeveloper";

export class DatabaseHelper {
  logger;
  cloudDbZone;

  constructor(context, logger) {
    this.logger = logger;
    const credential = Utils.getCredential(context, logger);
    try {
      // 初始化AGCClient
      logger.info("begin to init agcClient");
      let agcClient;
      try {
        agcClient = agc.AGCClient.getInstance();
      } catch {
        agc.AGCClient.initialize(credential);
        agcClient = agc.AGCClient.getInstance();
      }
      // 初始化AGConnectCloudDB实例
      logger.info("begin to init cloudDb");
      let cloudDbInstance;
      try {
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      } catch {
        cloudDb.AGConnectCloudDB.initialize(agcClient);
        cloudDbInstance = cloudDb.AGConnectCloudDB.getInstance(agcClient);
      }
      // 创建CloudDBZoneConfig配置对象，并设置云侧CloudDB zone名称，打开Cloud DB zone实例
      const cloudDBZoneConfig = new cloudDb.CloudDBZoneConfig(ZONE_NAME);
      this.cloudDbZone = cloudDbInstance.openCloudDBZone(cloudDBZoneConfig);
    } catch (err) {
      logger.error("init CloudDBZoneWrapper error: " + err);
    }
  }

  async queryResource(userid, resourceId) {
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      let likedIds = [];
      let collectedIds = [];
      let historyIds = [];

      const resourceQuery = cloudDb.CloudDBZoneQuery.where(resource);
      resourceQuery.equalTo('id', resourceId);
      const resourceResp = await this.cloudDbZone.executeQuery(resourceQuery);
      let resourceData = resourceResp.getSnapshotObjects();
      this.logger.info("query resource success ");
      console.log('resp=>', resourceData);
      if (resourceData.length > 0) {
        let dataQ: resource = resourceData[0];
        // 刷新访问数量
        const operator = cloudDb.CloudDBZoneObjectOperator.build(dataQ).increment('views_count', 1);
        await this.cloudDbZone.executeUpdate(operator);


        let detailData = new DetailResp();
        detailData.resourceId = dataQ.getId();
        detailData.title = dataQ.getTitle();
        detailData.type = dataQ.getType();
        detailData.webUrl = dataQ.getWeb_url();
        detailData.headerImageUrl = dataQ.getHeader_src();
        detailData.collectionCount = dataQ.getCollect_count();
        detailData.likesCount = dataQ.getLikes_count();
        detailData.viewsCount = dataQ.getViews_count();
        detailData.mediaSrc = dataQ.getMedia_src();

        if(userid){
          this.updateHistory(userid, resourceId)
          // let isLiked = await this.queryIsLiked(userid, resourceId);
          // let isCollected = await this.queryIsLiked(userid, resourceId);
          likedIds=await this.queryLikedIds(userid);
          collectedIds=await this.queryCollectedIds(userid);
          historyIds=await this.queryHistoryIds(userid);
          let isLiked=likedIds.indexOf(dataQ.getId())!==-1;
          let isCollected=collectedIds.indexOf(dataQ.getId())!==-1;
          detailData.isLiked = isLiked;
          detailData.isCollected = isCollected;
        }else{
          detailData.isLiked = null;
          detailData.isCollected = null;
        }
        // // 查询相关文章
        // let relatedIds: string[] = dataQ.getRelated().split(',');
        // let relatedSource: ResourceResp = []
        // if (relatedIds.length > 0) {
        //   const relatedQuery = cloudDb.CloudDBZoneQuery.where(resource);
        //   relatedQuery.in('id', relatedIds);
        //   const relatedResp = await this.cloudDbZone.executeQuery(relatedQuery);
        //   let relatedData = relatedResp.getSnapshotObjects();
        //   this.logger.info("query related success ");
        //   console.log('relatedResp=>', relatedData);
        //   if (relatedData.length > 0) {
        //     for (let i = 0; i < relatedData.length; i++) {
        //       let relatedQ = relatedData[i];
        //       relatedSource.push(
        //         new ResourceResp(
        //           relatedQ.getId(),
        //           relatedQ.getTitle(),
        //           relatedQ.getBrief(),
        //           relatedQ.getHeader_src(),
        //           relatedQ.getType(),
        //           relatedQ.getWeb_url(),
        //           relatedQ.getPublish_date(),
        //           relatedQ.getTopics(),
        //           relatedQ.getViews_count(),
        //           relatedQ.getCollect_count(),
        //           relatedQ.getLikes_count(),
        //           relatedQ.getTag(),
        //           relatedQ.getBanner_src(),
        //           relatedQ.getMedia_src(),
        //           likedIds.indexOf(dataQ.getId())!==-1, // isLiked
        //           collectedIds.indexOf(dataQ.getId())!==-1, // isCollected
        //           historyIds.indexOf(dataQ.getId())!==-1 // isViewed
        //         )
        //       )
        //     }
        //   }
        // }
        detailData.relatedSource = [];
        // detailData.relatedSource = relatedSource;
        return detailData;
      } else {
        return undefined;
      }
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryIsLiked(userid, resourceId) {
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const likeQuery = cloudDb.CloudDBZoneQuery.where(user_like);
      likeQuery.equalTo('user_id', userid);
      likeQuery.equalTo('resource_id', resourceId);
      const likeResp: number = await this.cloudDbZone.executeCountQuery(likeQuery, 'id');
      this.logger.info("query like resource success ");
      console.log('resp like=>', likeResp);
      return likeResp === 1
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryIsCollected(userid, resourceId) {
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const collectQuery = cloudDb.CloudDBZoneQuery.where(collect);
      collectQuery.equalTo('user_id', userid);
      collectQuery.equalTo('resource_id', resourceId);
      const collectResp: number = await this.cloudDbZone.executeCountQuery(collectQuery, 'id');
      this.logger.info("query like resource success ");
      console.log('resp collect=>', collectResp);
      return collectResp === 1
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async updateHistory(userid, resourceId) {
    // 更新访问记录
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const historyQuery = cloudDb.CloudDBZoneQuery.where(user_history);
      historyQuery.equalTo('user_id', userid);
      historyQuery.equalTo('resource_id', resourceId);
      const historyResp = await this.cloudDbZone.executeQuery(historyQuery);
      let historyData = historyResp.getSnapshotObjects();
      if (historyData.length > 0) {
        let historyItem: user_history = historyData[0];
        historyItem.setBrowse_time(new Date())
        const historyResp: number = await this.cloudDbZone.executeUpsert(historyItem);
      } else {
        let historyNew = new user_history();
        historyNew.setBrowse_time(new Date());
        historyNew.setId(userid + resourceId);
        historyNew.setUser_id(userid);
        historyNew.setResource_id(resourceId);
        const historyResp: number = await this.cloudDbZone.executeInsert(historyNew);
      }
      this.logger.info("query history resource success ");
      console.log('resp history=>', historyResp);
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryLikedIds(userid) {
    let likedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const likeQuery = cloudDb.CloudDBZoneQuery.where(user_like);
      likeQuery.equalTo('user_id', userid);
      const likeResp = await this.cloudDbZone.executeQuery(likeQuery);
      let likeData = likeResp.getSnapshotObjects();
      this.logger.info("query like resource success ");
      console.log('resp like=>', likeResp);
      for (let index = 0; index < likeData.length; index++) {
        const element: user_like = likeData[index];
        likedIds.push(element.getResource_id());
      }
      return likedIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryCollectedIds(userid) {
    let collectedIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const collectedQuery = cloudDb.CloudDBZoneQuery.where(collect);
      collectedQuery.equalTo('user_id', userid);
      const collectedResp = await this.cloudDbZone.executeQuery(collectedQuery);
      let collectedData = collectedResp.getSnapshotObjects();
      this.logger.info("query collected resource success ");
      console.log('resp collected=>', collectedResp);
      for (let index = 0; index < collectedData.length; index++) {
        const element: collect = collectedData[index];
        collectedIds.push(element.getResource_id());
      }
      return collectedIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }

  async queryHistoryIds(userid) {
    let historyIds = [];
    if (!this.cloudDbZone) {
      console.log("CloudDBClient is null, try re-initialize it");
      return;
    }
    try {
      const historyQuery = cloudDb.CloudDBZoneQuery.where(user_history);
      historyQuery.equalTo('user_id', userid);
      const historyResp = await this.cloudDbZone.executeQuery(historyQuery);
      let historyData = historyResp.getSnapshotObjects();
      this.logger.info("query historyData resource success ");
      console.log('resp historyData=>', historyResp);
      for (let index = 0; index < historyData.length; index++) {
        const element: user_history = historyData[index];
        historyIds.push(element.getResource_id());
      }
      return historyIds;
    } catch (error) {
      this.logger.info("query resource error " + error);
    }
  }
}